package com.sdleyou.treepro.common.service.impl;

import com.alibaba.fastjson.JSON;
import com.sdleyou.treepro.common.exception.ServiceException;
import com.sdleyou.treepro.common.model.convert.FriendDO2FriendVOConverter;
import com.sdleyou.treepro.common.model.dao.CompanyDO;
import com.sdleyou.treepro.common.model.dao.FriendDO;
import com.sdleyou.treepro.common.model.dao.Page;
import com.sdleyou.treepro.common.model.dao.UserDO;
import com.sdleyou.treepro.common.model.enums.ErrorCodeEnum;
import com.sdleyou.treepro.common.model.vo.FriendVO;
import com.sdleyou.treepro.common.model.vo.NearbyVO;
import com.sdleyou.treepro.common.model.vo.UserVO;
import com.sdleyou.treepro.common.service.MongoPageManager;
import com.sdleyou.treepro.common.service.UserFriendManager;
import com.sdleyou.treepro.common.service.UserManager;
import com.sdleyou.treepro.common.utils.DateUtil;
import com.sdleyou.treepro.common.utils.DistanceUtils;
import org.apache.http.util.TextUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class UserFriendManagerImpl implements UserFriendManager {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private MongoPageManager mongoPageManager;
    @Autowired
    private UserManager userManager;

    /**
     * 好友列表
     */
    @Override
    public Page<FriendVO> getUserFriendList(String userId, Integer pageNum, Integer pageSize) {
        Query query = new Query();
        Criteria c = Criteria.where("user_id").is(userId);
        query.addCriteria(c);

        List<FriendDO> friendDOS = mongoTemplate.find(query, FriendDO.class);
        List<FriendVO> collect = friendDOS.stream().map(FriendDO2FriendVOConverter::convert).collect(Collectors.toList());

        for (FriendVO friendVO : collect) {
            Aggregation aggregation = Aggregation.newAggregation(
                    Aggregation.match(Criteria.where("user_id").is(friendVO.getFriendId())),
                    Aggregation.group("user_id").first("$total_tree").as("total_tree").first("$fertility").as("fertility").first("$total_value").as("total_value").first("$water").as("water"));
            AggregationResults<Map> ans = mongoTemplate.aggregate(aggregation, "{RRZS}_collection_user", Map.class);
            List<Map> mapList = ans.getMappedResults();
            if (mapList != null && mapList.size() > 0) {
                Integer total_tree = (Integer) mapList.get(0).get("total_tree");
                friendVO.setTotalTree(total_tree);
                Integer fertility = (Integer) mapList.get(0).get("fertility");
                if(fertility==100){
                    friendVO.setIsFertility(false);
                }else {
                    friendVO.setIsFertility(true);
                }
                Integer water = (Integer) mapList.get(0).get("water");
                if (water != null) {
                    if (water > 4) {
                        friendVO.setIsWater(true);
                    } else {
                        friendVO.setIsWater(false);
                    }
                } else {
                    friendVO.setIsWater(false);
                }
                Integer total_value = (Integer) mapList.get(0).get("total_value");
                friendVO.setTotalValue(total_value);
            }

            aggregation = Aggregation.newAggregation(
                    Aggregation.match(Criteria.where("user_id").is(friendVO.getFriendId()).and("tree_status").is(0)),
                    Aggregation.group("user_id").first("$worm_num").as("worm_num"));
            ans = mongoTemplate.aggregate(aggregation, "{RRZS}_collection_user_tree", Map.class);
            mapList = ans.getMappedResults();
            if (mapList != null && mapList.size() > 0) {
                Integer worm_num = (Integer) mapList.get(0).get("worm_num");
                if(worm_num>0){
                    friendVO.setIsPest(true);
                }else {
                    friendVO.setIsPest(false);
                }
            }
        }
        collect.sort(new Comparator<FriendVO>() {
            @Override
            public int compare(FriendVO o1, FriendVO o2) {
                if(o1.getTotalTree()!=null && o2.getTotalTree()!=null)
                    if(!o1.getTotalTree().equals(o2.getTotalTree()))
                        return o2.getTotalTree().compareTo(o1.getTotalTree());
                return 0;
            }
        });
        long total = 0;
        if(collect.size()>0){
            total = collect.size();
        }
        return new Page<>(pageNum, total, pageSize, collect);

//        LookupOperation lookupOperation=LookupOperation.newLookup().
//                from("{RRZS}_collection_user").  //关联从表名
//                localField("friend_id").     //主表关联字段
//                foreignField("user_id").//从表关联的字段
//                as("result");   //查询结果名
//        AggregationOperation match = Aggregation.match(Criteria.where("user_id").is(userId));
//        Aggregation aggregation=Aggregation.newAggregation(match, lookupOperation); //多条件
//        List<Map> results = mongoTemplate.aggregate(aggregation,"{RRZS}_collection_user_friend", Map.class).getMappedResults();
//        //上面的DYNC_EXT_TestInstance必须是查询的主表名
//        System.out.println(JSON.toJSONString(results));
//        return new Page(pageNum, 100L, pageSize, results);
    }

    /**
     * 添加好友
     */
    @Override
    public Map<String, String> addFriend(String userId, String friendId, String resource) {
        UserVO friend = userManager.userInfo(friendId);
        UserVO user = userManager.userInfo(userId);
        if(friend==null){
            throw new ServiceException(ErrorCodeEnum.E100.code(), "用户不存在");
        }
        if(friend==user){
            throw new ServiceException(ErrorCodeEnum.E100.code(), "用户不存在");
        }

        Query query = new Query(Criteria.where("user_id").is(userId).and("friend_id").is(friendId));
        FriendDO friendOne = mongoTemplate.findOne(query, FriendDO.class);
        if(friendOne == null){
            //throw new ServiceException(ErrorCodeEnum.E500.code(), "已经是好友了");
            FriendDO friendDO = new FriendDO();
            friendDO.setUserId(userId);
            friendDO.setFriendId(friendId);
            friendDO.setNickname(friend.getNickname());
            friendDO.setFace(friend.getFace());
            friendDO.setCreatedAt(DateUtil.getDateline());
            friendDO.setResource(resource);
            friendDO.setGmtCreate(DateUtil.getDateline());
            friendDO.setGmtModified(DateUtil.getDateline());

            FriendDO userDO = new FriendDO();
            userDO.setUserId(friendId);
            userDO.setFriendId(userId);
            userDO.setNickname(user.getNickname());
            userDO.setFace(user.getFace());
            userDO.setCreatedAt(DateUtil.getDateline());
            userDO.setResource(resource);
            userDO.setGmtCreate(DateUtil.getDateline());
            userDO.setGmtModified(DateUtil.getDateline());

            mongoTemplate.insert(friendDO);
            mongoTemplate.insert(userDO);
        }

        return null;
    }

    /**
     * 附近的人
     */
    @Override
    public List<NearbyVO> getNearby(String userId, Double userLng, Double userLat, Double distance) {
        //查询好友列表
        Query q = new Query(Criteria.where("user_id").is(userId));
        List<FriendDO> friendDOS = mongoTemplate.find(q, FriendDO.class);
        ArrayList<String> ids = new ArrayList<>();
        for (FriendDO friendDO : friendDOS) {
            if(friendDO!=null){
                ids.add(friendDO.getFriendId());
            }
        }
        //筛选条件 跳过好友
        Query query = new Query(Criteria.where("user_id").nin(ids));
        query.with(Sort.by(Sort.Order.desc("last_login_time")));
        List<UserDO> all = mongoTemplate.find(query, UserDO.class);
        List<NearbyVO> result = new ArrayList<>();
        for (int i=0;i<all.size();i++){
            UserDO userDO = all.get(i);
            //跳过自己
            if(userId.equals(userDO.getUserId())){
                continue;
            }
            if(userDO.getLongitude()!=null && userDO.getLatitude()!=null) {
                Double resultDistance = DistanceUtils.getDistance(userLng, userLat, Double.parseDouble(userDO.getLongitude()), Double.parseDouble(userDO.getLatitude()));
                if (resultDistance.compareTo(distance) < 0) {
                    if (i == 100) {
                        break;
                    }
                    NearbyVO nearbyVO = new NearbyVO();
                    BeanUtils.copyProperties(userDO, nearbyVO);
                    nearbyVO.setDistance(resultDistance);
                    result.add(nearbyVO);
                }
            }
        }
        result.sort(new Comparator<NearbyVO>() {
            @Override
            public int compare(NearbyVO o1, NearbyVO o2) {
                return o1.getDistance().compareTo(o2.getDistance());
            }
        });
        return canMakeFriends(result, userId);
    }

    /**
     * 判断能否添加好友
     *
     * @param nearbyVO
     * @param userId
     * @return
     */
    private List<NearbyVO> canMakeFriends(List<NearbyVO> nearbyVO, String userId) {
        if (nearbyVO != null && nearbyVO.size() > 0) {
            for (NearbyVO vo : nearbyVO) {
                if (!vo.getUserId().equals(userId)) { //不是自己
                    Query query = new Query(Criteria.where("user_id").is(userId).and("friend_id").is(vo.getUserId()));
                    FriendDO friendDO = mongoTemplate.findOne(query, FriendDO.class);
                    if (friendDO != null) {
                        vo.setMakeFriends(false); //已经加过了
                    } else {
                        vo.setMakeFriends(true); //可以加
                    }
                } else {
                    vo.setMakeFriends(false); //是自己 不能加
                }
            }
        }
        return nearbyVO;
    }

    /**
     * 更新好友数据
     */
    public void update(String userId, String name, String face){
        Query query = new Query(Criteria.where("friend_id").is(userId));
        Update update = new Update();
        if(!TextUtils.isEmpty(name)) {
            update.set("nickname", name);
        }
        if(!TextUtils.isEmpty(face)) {
            update.set("face", face);
        }
        update.set("gmt_modified", DateUtil.getDateline());
        mongoTemplate.updateMulti(query, update, FriendDO.class);
    }
}
